﻿using System;
using System.IO;
using System.Runtime.InteropServices;

namespace CabConfigProvisioning
{
    public class GcFile : IDisposable
    {
        private readonly Stream _stream;
        private readonly GCHandle _gch;

        public GcFile(String sFilePath)
        {
            if (!MemoryCache.Instance.TryGetStream(sFilePath, out _stream))
                _stream = new FileStream(sFilePath, FileMode.Open, FileAccess.Read);
            _gch = GCHandle.Alloc(_stream);
        }

        public GcFile(FileInfo file) : this(file.FullName)
        {
        }


        public IntPtr Handle
        {
            get { return (IntPtr) _gch; }
        }

        public void Dispose()
        {
            _stream.Close();
            _gch.Free();
        }

        public static IntPtr CreateNew()
        {
            return (IntPtr) GCHandle.Alloc(new MemoryStream());
        }

        public static byte[] Close(IntPtr hFile)
        {
            Stream stream = FxiHelpers.StreamFromHandle(hFile);
            int nSize = (int) stream.Length;
            byte[] buf = new byte[nSize];
            if (nSize > 0)
            {
                stream.Position = 0;
                int nRead = stream.Read(buf, 0, nSize);
                if(nRead != nSize)
                    throw new IOException(nRead + " bytes read, expected " + nSize +"!");
            }
            stream.Close();
            ((GCHandle) hFile).Free();
            return buf;
        }
    }
}
